package com.sixbro.shiro.jwt.service.token;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.bxs.crypto.AesUtils;
import com.bxs.rbac.shiro.jwt.config.shiro.TokenProperties;
import com.bxs.rbac.shiro.jwt.domain.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * <p>
 *
 * </p>
 *
 * @Author: Mr.Lu
 * @Since: 2020/6/17 17:26
 */
@Service
public class TokenServiceImpl implements TokenService {

    @Autowired
    private TokenProperties properties;

    @Override
    public String generate(User user) throws Exception {
        // 附带username信息
        return JWT.create()
                .withSubject( AesUtils.encrypt16( JSONObject.toJSONString( user ) ) )
                .withExpiresAt( getExpirationDate() )
                .sign( Algorithm.HMAC256( user.getPassword() ) );
    }

    @Override
    public User getUser(String token) throws Exception {
        JSONObject object = JSONObject.parseObject( AesUtils.decrypt( JWT.decode( token ).getSubject() ) );
        return JSONObject.toJavaObject(object, User.class);
    }

    @Override
    public Boolean verify(String token, User user) {
        try {
            String encrypt16 = AesUtils.encrypt16(JSONObject.toJSONString(user));

            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256( user.getPassword() ))
                    .withSubject(encrypt16)
                    .build();
            DecodedJWT jwt = jwtVerifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    private Date getExpirationDate( ) {
        return new Date( System.currentTimeMillis( ) + ( properties.getExpiration() * 24 * 60 * 60 * 1000) );
    }
}
